import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import com.ice.tar.TarEntry;
import com.ice.tar.TarInputStream;

public class Unzip {
    public static void unzip(String file, String location) {

	if (!location.endsWith("/"))
	    location += "/";
	try {
	    ZipInputStream input = new ZipInputStream(new FileInputStream(file));
	    ZipEntry entry = null;
	    while ((entry = input.getNextEntry()) != null) {
		// create folder structure
		if (entry.isDirectory()) {
		    File dir = new File(location + entry.getName());
		    dir.mkdirs();
		} else {
		    String dir_path = location + entry.getName();
		    dir_path = dir_path.substring(0, dir_path.lastIndexOf('/'));
		    File dir = new File(dir_path);
		    dir.mkdirs();
		}
		File f = new File(location + entry.getName());
		FileOutputStream output = new FileOutputStream(f);
		BufferedOutputStream output_stream = new BufferedOutputStream(
			output, 4096);
		byte[] buffer = new byte[4096];
		int count;
		while ((count = input.read(buffer)) != -1) {
		    output_stream.write(buffer, 0, count);
		}
		output_stream.flush();
		output_stream.close();
	    }
	    input.close();
	} catch (Exception exception) {
	    System.err.println("[Error] " + exception.toString());
	}
    }

    private static InputStream getInputStream(String tarFileName)
	    throws Exception {

	if (tarFileName.substring(tarFileName.lastIndexOf(".") + 1,
		tarFileName.lastIndexOf(".") + 3).equalsIgnoreCase("gz")) {
	    return new GZIPInputStream(new FileInputStream(
		    new File(tarFileName)));

	} else {
	    return new FileInputStream(new File(tarFileName));
	}
    }

    public static void untar(String file, String untarDir) {
	try {
	    InputStream in = getInputStream(file);
	    TarInputStream tin = new TarInputStream(in);
	    TarEntry tarEntry = tin.getNextEntry();
	    if (new File(untarDir).exists()) {
		while (tarEntry != null) {
		    File destPath = new File(untarDir + File.separatorChar
			    + tarEntry.getName());
		    if (!tarEntry.isDirectory()) {
			FileOutputStream fout = new FileOutputStream(destPath);
			tin.copyEntryContents(fout);
			fout.close();
		    } else {
			destPath.mkdir();
		    }
		    tarEntry = tin.getNextEntry();
		}
		tin.close();
	    } else {
		System.err.println("That destination directory doesn't exist! "
			+ untarDir);
	    }
	} catch (Exception e) {
	    System.err.println("[Error] " + e.toString());
	}
    }

    public static void extract(String file, String directory) {
	String ext = "";
	try {
	    ext = file.substring(file.lastIndexOf('.')).toLowerCase();
	} catch (Exception e) {
	}
	if (ext.equals(".zip")) {
	    unzip(file, directory);
	} else if (ext.equals(".gz")) {
	    untar(file, directory);
	} else {
	    System.err.println("[Error] Unsupported archive file: " + file);
	}
    }

    public static void fromJar(String file, String directory) {
	if (!directory.endsWith("/"))
	    directory += "/";

	try {
	    InputStream stream = Main.class.getResourceAsStream("/" + file);
	    DataInputStream in = new DataInputStream(stream);
	    BufferedReader br = new BufferedReader(new InputStreamReader(in));
	    FileWriter fwrite = new FileWriter(directory + file);
	    BufferedWriter fout = new BufferedWriter(fwrite);
	    String line;

	    while ((line = br.readLine()) != null) {
		fout.write(line);
		fout.write("\n");
	    }
	    fout.close();
	    in.close();
	} catch (Exception e) {
	    System.err.println("[Error] Cannot extract " + file + ": "
		    + e.toString());
	}
    }

}
